package com.huixuebao.after.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.huixuebao.after.dto.*;
import com.huixuebao.after.entity.*;
import com.huixuebao.after.mapper.*;
import com.huixuebao.after.service.CourseService;
import com.huixuebao.common.bean.ApiResult;
import com.huixuebao.common.enumeration.ResultCodeEnum;
import com.huixuebao.common.util.ConvertUtils;
import com.huixuebao.common.util.JWTUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

@Slf4j
@Service
public class CourseServiceImpl implements CourseService {

    @Autowired
    CourseMapper courseMapper;

    @Autowired
    CategoryMapper categoryMapper;

    @Autowired
    DictionaryMapper dictionaryMapper;

    @Autowired
    MechanismMapper mechanismMapper;

    @Autowired
    UserMapper userMapper;

    @Override
    public ApiResult<List<CourseDTO>> saveCourseDTO(List<CourseDTO> list) {
        if (CollUtil.isNotEmpty(list)) {
            for (CourseDTO courseDTO : list) {

                if (StrUtil.isNotBlank(courseDTO.getCategoryId())) {
                    String[] category = courseDTO.getCategoryId().split("-");
                    if (category.length > 0) {
                        StringBuffer buffer = new StringBuffer(",");
                        for (String categoryId : category) {
                            if (StrUtil.isNotBlank(categoryId)) {
                                List<CategoryEntity> categorys = categoryMapper.selectList(new LambdaQueryWrapper<CategoryEntity>()
                                        .eq(CategoryEntity::getName, categoryId).likeLeft(CategoryEntity::getClassList, buffer.toString()));
                                if (categorys.size() == 1) {
                                    buffer.append(categorys.get(0).getId() + ",");
                                }

                            }
                        }
                        String[] categories = buffer.toString().split(",");
                        courseDTO.setCategoryId(categories[categories.length - 1]);
                    }
                }
                if (StrUtil.isNotBlank(courseDTO.getClassType())) {
                    DictionaryEntity classType = dictionaryMapper.selectOne(new LambdaQueryWrapper<DictionaryEntity>()
                            .eq(DictionaryEntity::getName, courseDTO.getClassType()).eq(DictionaryEntity::getPid, "9"));
                    if (ObjectUtil.isNotNull(classType)) {
                        courseDTO.setClassType(classType.getId());
                    }
                }
                if (StrUtil.isNotBlank(courseDTO.getSchoolAge())) {
                    DictionaryEntity schoolAge = dictionaryMapper.selectOne(new LambdaQueryWrapper<DictionaryEntity>()
                            .eq(DictionaryEntity::getName, courseDTO.getSchoolAge()).eq(DictionaryEntity::getPid, "7"));
                    if (ObjectUtil.isNotNull(schoolAge)) {
                        courseDTO.setSchoolAge(schoolAge.getId());
                    }
                }
                if (StrUtil.isNotBlank(courseDTO.getTeachingMethod())) {
                    DictionaryEntity teachingMethod = dictionaryMapper.selectOne(new LambdaQueryWrapper<DictionaryEntity>()
                            .eq(DictionaryEntity::getName, courseDTO.getTeachingMethod()).eq(DictionaryEntity::getPid, "8"));
                    if (ObjectUtil.isNotNull(teachingMethod)) {
                        courseDTO.setTeachingMethod(teachingMethod.getId());
                    }
                }
                MechanismEntity mechanismEntity = null;
                if (StrUtil.isNotBlank(courseDTO.getMechanismName())) {
                    List<MechanismEntity> mechanismEntities = mechanismMapper.selectList(new LambdaQueryWrapper<MechanismEntity>().eq(MechanismEntity::getName, courseDTO.getMechanismName()));
                    if (CollUtil.isNotEmpty(mechanismEntities)) {
                        mechanismEntity = mechanismEntities.get(0);
                    }
                }

                CourseEntity entity = null;//courseMapper.selectOne(new LambdaQueryWrapper<CourseEntity>()
                //.eq(CourseEntity::getCourseName, courseDTO.getCourseName())
                //.eq(CourseEntity::getMechanismName, courseDTO.getMechanismName())
                //.eq(CourseEntity::getBrand, courseDTO.getBrand()));
                if (ObjectUtil.isNotNull(entity)) {
                    BeanUtil.copyProperties(courseDTO, entity, CopyOptions.create().setIgnoreNullValue(true));
                    if (mechanismEntity != null) {
                        entity.setCourseState("2");
                        //将外包生成的商户号匹配到课程当中
                        entity.setMechanismNo(mechanismEntity.getUserNubmer());
                        //将机构id放到课程中，匹配上机构中显示的课程
                        entity.setMechanismId(mechanismEntity.getId());
                    }
                    int count = courseMapper.updateById(entity);
                    log.info("userNumber={}, count={}", entity.getMechanismNo(), count);

                } else {
                    entity = new CourseEntity();
                    BeanUtil.copyProperties(courseDTO, entity, CopyOptions.create().setIgnoreNullValue(true));
                    entity.setMechanismName(courseDTO.getMechanismName());
                    entity.setBrand(courseDTO.getBrand());
                    entity.setMechanismId(mechanismEntity.getId());
                    entity.setCourseState("2");
                    if (mechanismEntity != null) {
                        entity.setMechanismNo(mechanismEntity.getUserNubmer());
                    }
                    entity.setId(IdUtil.fastSimpleUUID());
                    courseMapper.insert(entity);
                    log.info("------------couse----------------");
                }
            }
        }
        ApiResult apiResult = new ApiResult();
        apiResult.setData(list);
        return apiResult;
    }

    @Override
    public ApiResult getListCourse(Integer current, Integer size, String courseName, String mechanismName, String courseState, HttpServletRequest request) {
        ApiResult apiResult = new ApiResult();
        String userId = JWTUtils.getUserId(request);
        String userType = JWTUtils.getUserType(request);
        UserEntity userEntity = userMapper.selectById(userId);
        try {
            if (ObjectUtil.isNotNull(current) && ObjectUtil.isNotNull(size)) {
                if("0".equals(userType)){
                    IPage<CourseEntity> page = new Page<>(current, size);
                    IPage<CourseEntity> entityIPage = courseMapper.selectPage(page, new LambdaQueryWrapper<CourseEntity>().orderByDesc(CourseEntity::getCreateDate)
                            .like(StrUtil.isNotBlank(courseName), CourseEntity::getCourseName, courseName)
                            .like(StrUtil.isNotBlank(mechanismName), CourseEntity::getMechanismName, mechanismName)
                            .like(StrUtil.isNotBlank(courseState), CourseEntity::getCourseState, courseState));
                    IPage<CourseAfterDTO> dtoPage = ConvertUtils.convertToDTOPage(entityIPage, CourseAfterDTO.class);
                    apiResult.setData(dtoPage);
                    apiResult.setSuccess(true);
                    apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                    apiResult.setMessage("管理端获取课程分页列表成功!!");
                }else {
                    IPage<CourseEntity> page = new Page<>(current, size);
                    UserEntity id = userMapper.selectOne(new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getId,userId));
                    MerchantsDTO dto=new MerchantsDTO();
                    dto.setId(userEntity.getMechanismId());
                    getChilds1(dto);
                    List<String> ids = new ArrayList<>();
                    getIdList(dto,ids);
                    IPage<CourseEntity> entityIPage = courseMapper.selectPage(page, new LambdaQueryWrapper<CourseEntity>().in(ids.size()>0,CourseEntity::getMechanismId, ids).orderByDesc(CourseEntity::getCreateDate)
                            .like(StrUtil.isNotBlank(courseName), CourseEntity::getCourseName, courseName)
                            .like(StrUtil.isNotBlank(mechanismName), CourseEntity::getMechanismName, mechanismName)
                            .like(StrUtil.isNotBlank(courseState), CourseEntity::getCourseState, courseState));

                    entityIPage.getRecords().forEach(entity -> {
                        List<CourseEntity> list = courseMapper.selectList(new LambdaQueryWrapper<CourseEntity>().eq(CourseEntity::getMechanismId, entity.getId()));
                        List<String> mechanismId = list.stream().map(CourseEntity::getMechanismId).collect(Collectors.toList());
                        entity.setCourseIds(mechanismId);
                    });
                    IPage<CourseAfterDTO> dtoPage = ConvertUtils.convertToDTOPage(entityIPage, CourseAfterDTO.class);
                    apiResult.setData(dtoPage);
                    apiResult.setSuccess(true);
                    apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                    apiResult.setMessage("机构端获取课程分页列表成功!!");
                }
            } else {
                List<CourseEntity> list = courseMapper.selectList(new LambdaQueryWrapper<CourseEntity>().orderByDesc(CourseEntity::getCreateDate)
                        .like(StrUtil.isNotBlank(courseName), CourseEntity::getCourseName, courseName)
                        .like(StrUtil.isNotBlank(mechanismName), CourseEntity::getMechanismName, mechanismName)
                        .like(StrUtil.isNotBlank(courseState), CourseEntity::getCourseState, courseState));
                List<CourseAfterDTO> doList = ConvertUtils.convertToDTOList(list, CourseAfterDTO.class);
                apiResult.setData(doList);
                apiResult.setSuccess(true);
                apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                apiResult.setMessage("获取课程列表成功!!");
            }
        } catch (Exception e) {
            log.info("获取课程列表信息失败!!");
            apiResult.setSuccess(true);
            apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
            apiResult.setMessage("获取课程列表信息失败!!" + e.getMessage());
        }
        return apiResult;
    }

    private List<MerchantsDTO> listDTO1(String pid) {
        List<MechanismEntity> list = mechanismMapper.selectList(new LambdaQueryWrapper<MechanismEntity>().eq(MechanismEntity::getPid, pid));
        List<MerchantsDTO> result = new ArrayList<>();
        list.forEach(entity -> {
            MerchantsDTO dto = new MerchantsDTO();
            BeanUtil.copyProperties(entity, dto);
            result.add(dto);
        });
        return result;
    }

    private void getChilds1(MerchantsDTO dto) {
        List<MerchantsDTO> childs = listDTO1(dto.getId());
        dto.setChildren(childs);
        for (MerchantsDTO getChilds : childs) {
            getChilds1(getChilds);
        }
    }

    private void getIdList(MerchantsDTO dto,List<String> ids){
        ids.add(dto.getId());
        dto.getChildren().forEach((merchantsDTO)->{
            getIdList(merchantsDTO,ids);
        });
    }
    /**
     * 添加课程信息
     *
     * @param courseAfterDTO
     * @return
     */
    @Override
    public ApiResult addCourse(CourseListDTO courseAfterDTO,HttpServletRequest request) {
        ApiResult apiResult = new ApiResult();
        String userType = JWTUtils.getUserType(request);
        try {
            if ("0".equals(userType)) {
                CourseEntity courseEntity = setCourse(courseAfterDTO);
                courseEntity.setCourseState("2");
                //写入数据到mapper
                courseMapper.insert(courseEntity);
                apiResult.setSuccess(true);
                apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                apiResult.setMessage("商户端添加课程信息成功!!");
            } else {
                CourseEntity courseEntity = setCourse(courseAfterDTO);
                courseEntity.setCourseState("0");
                //写入数据到mapper
                courseMapper.insert(courseEntity);
                apiResult.setSuccess(true);
                apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                apiResult.setMessage("机构端添加课程信息成功!!");
            }
        } catch (Exception e) {
            log.info("添加课程失败!!");
            apiResult.setSuccess(false);
            apiResult.setCode(ResultCodeEnum.FAILURE.getCode());
            apiResult.setMessage("添加课程信息失败!!" + e.getMessage());
        }
        return apiResult;
    }

    /**
     * 写入到数据库
     * @param
     * @return
     */
    private CourseEntity setCourse(CourseListDTO courseAfterDTO){

        CourseEntity courseEntity = new CourseEntity();
        MechanismEntity mechanismEntity = new MechanismEntity();
        //课程图片地址
        String courseUrl = courseAfterDTO.getCourseUrl();
        //课程名称
        String courseName = courseAfterDTO.getCourseName();
        //课程价格
        BigDecimal coursePrice = courseAfterDTO.getCoursePrice();
        //供货价格
        BigDecimal supplyPrice = courseAfterDTO.getSupplyPrice();
        //课程分类
        String categoryId = courseAfterDTO.getCategoryId();
        //学龄阶段
        Integer schoolAge = courseAfterDTO.getSchoolAge();
        //授课方式
        Integer teachingMethod = courseAfterDTO.getTeachingMethod();
        //课时总数
        Integer total = courseAfterDTO.getTotal();
        //班型
        Integer classType = courseAfterDTO.getClassType();
        //有效期
        Date validityTime = courseAfterDTO.getValidityTime();
        //预约信息
        String appointment = courseAfterDTO.getAppointment();
        //图文描述（课程描述）
        String content = courseAfterDTO.getContent();
        String userNumber = courseAfterDTO.getUserNumber();
        String mechanismId = courseAfterDTO.getMechanismId();
        //判断所以必填参数不为空
        if (StrUtil.isNotEmpty(courseUrl) && StrUtil.isNotEmpty(courseName)
                && BeanUtil.isNotEmpty(coursePrice) && BeanUtil.isNotEmpty(supplyPrice) && StrUtil.isNotEmpty(categoryId)
                && ObjectUtil.isNotNull(schoolAge) && ObjectUtil.isNotNull(teachingMethod) && ObjectUtil.isNotNull(total)
                && ObjectUtil.isNotNull(classType) && StrUtil.isNotEmpty(appointment) && StrUtil.isNotEmpty(mechanismId)) {
            MechanismEntity mechanismDTO = mechanismMapper.selectOne(new LambdaQueryWrapper<MechanismEntity>().eq(MechanismEntity::getId,mechanismId));
            courseEntity.setMechanismId(mechanismId);
            courseEntity.setCourseUrl(courseUrl);
            courseEntity.setMechanismName(mechanismDTO.getName());
            courseEntity.setCourseName(courseName);
            courseEntity.setCoursePrice(coursePrice);
            courseEntity.setSupplyPrice(supplyPrice);
            courseEntity.setCategoryId(categoryId);
            courseEntity.setSchoolAge(schoolAge);
            courseEntity.setTeachingMethod(teachingMethod);
            courseEntity.setTotal(total);
            courseEntity.setClassType(classType);
            courseEntity.setValidityTime(validityTime);
            courseEntity.setAppointment(appointment);
            courseEntity.setMechanismNo(userNumber);
            courseEntity.setContent(content);
            courseEntity.setMechanismNo(mechanismDTO.getUserNubmer());
            courseEntity.setBrand(mechanismDTO.getBrand());
            courseEntity.setCreateDate(new DateTime());
        }
        return courseEntity;
    }

    /**
     * 编辑课程信息
     *
     * @param courseAfterDTO
     * @return
     */
    @Override
    public ApiResult editCourse(CourseListDTO courseAfterDTO) {
        ApiResult apiResult = new ApiResult();
        try {
            //课程名称
            String courseName = courseAfterDTO.getCourseName();
            String courseId = courseAfterDTO.getId();
            //课程分类
            String categoryId = courseAfterDTO.getCategoryId();
            //供货价格
            BigDecimal supplyPrice = courseAfterDTO.getSupplyPrice();
            //课程价格
            BigDecimal coursePrice = courseAfterDTO.getCoursePrice();
            //学龄阶段
            Integer schoolAge = courseAfterDTO.getSchoolAge();
            //授课方式
            Integer teachingMethod = courseAfterDTO.getTeachingMethod();
            //课时总数
            Integer total = courseAfterDTO.getTotal();
            //班型
            Integer classType = courseAfterDTO.getClassType();
            //有效期
            Date validityTime = courseAfterDTO.getValidityTime();
            //预约信息
            String appointment = courseAfterDTO.getAppointment();
            //商户名称
            String mechanismName = courseAfterDTO.getMechanismName();
            //图文描述（课程描述）
            String content = courseAfterDTO.getContent();
            //课程图片地址
            String courseUrl = courseAfterDTO.getCourseUrl();
            String courseState = courseAfterDTO.getCourseState();
            //判断所以必填参数不为空
            if (StrUtil.isNotEmpty(courseId) && StrUtil.isNotEmpty(courseName) && BeanUtil.isNotEmpty(coursePrice)
                    && BeanUtil.isNotEmpty(supplyPrice) && StrUtil.isNotEmpty(categoryId) && ObjectUtil.isNotNull(schoolAge)
                    && ObjectUtil.isNotNull(teachingMethod) && ObjectUtil.isNotNull(total) && ObjectUtil.isNotNull(classType)
                    && StrUtil.isNotEmpty(appointment) && StrUtil.isNotEmpty(courseUrl) && StrUtil.isNotEmpty(mechanismName))
            {
                CourseEntity id = courseMapper.selectOne(new LambdaQueryWrapper<CourseEntity>().eq(CourseEntity::getId,courseId));
                if (id == null){
                    apiResult.setSuccess(false);
                    apiResult.setCode(ResultCodeEnum.FAILURE.getCode());
                    apiResult.setMessage("没有获取到课程信息Id!!");
                }else {
                    id.setMechanismName(mechanismName);
                    id.setCourseUrl(courseUrl);
                    id.setSchoolAge(schoolAge);
                    id.setCourseName(courseName);
                    id.setCoursePrice(coursePrice);
                    id.setSupplyPrice(supplyPrice);
                    id.setCategoryId(categoryId);
                    id.setTeachingMethod(teachingMethod);
                    id.setTotal(total);
                    id.setClassType(classType);
                    id.setValidityTime(validityTime);
                    id.setAppointment(appointment);
                    id.setContent(content);
                    id.setCourseState(courseState);
                    id.setUpdateDate(new DateTime());
                    courseMapper.updateById(id);
                }
                apiResult.setSuccess(true);
                apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                apiResult.setMessage("编辑课程信息成功!!");
            }else {
                log.info("必填字段不能为空");
                apiResult.setSuccess(false);
                apiResult.setCode(ResultCodeEnum.FAILURE.getCode());
                apiResult.setMessage("课程信息必填字段不能为空");
            }
        } catch (Exception e) {
            apiResult.setSuccess(false);
            apiResult.setCode(ResultCodeEnum.FAILURE.getCode());
            apiResult.setMessage("课程信息更新失败!!" + e.getMessage());
        }
        return apiResult;
    }

    /**
     * 获取课程分类树
     * @return
     */
    @Override
    public ApiResult<List<CategoryAfterDTO>> categoryTree() {
        ApiResult apiResult = new ApiResult();
       try {
           List<CategoryAfterDTO> categoryRoot = listDTO("0");
           for (CategoryAfterDTO dto : categoryRoot) {
               getChild(dto);
           }
           apiResult.setData(categoryRoot);
           apiResult.setSuccess(true);
           apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
           apiResult.setMessage("获取课程分类成功!!");
       }catch (Exception e){
            apiResult.setSuccess(false);
            apiResult.setCode(ResultCodeEnum.FAILURE.getCode());
            apiResult.setMessage("获取课程分类失败!!");
        }
        return apiResult;
    }

    @Override
    public ApiResult updateCourseState(CourseIdDTO courseIdDTO) {
        ApiResult apiResult = new ApiResult();
        try{
            String id = courseIdDTO.getId();
            String courseState = courseIdDTO.getCourseState();
            String remarks = courseIdDTO.getRemarks();
            CourseEntity courseId = courseMapper.selectById(id);
            if(courseId != null){
                courseId.setCourseState(courseState);
                courseId.setRemarks(remarks);
                courseMapper.updateById(courseId);
                apiResult.setSuccess(true);
                apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                apiResult.setMessage("更新课程状态成功!!");
            }else {
                log.info("当前课程id为空!!!");
                apiResult.setSuccess(false);
                apiResult.setCode(ResultCodeEnum.FAILURE.getCode());
                apiResult.setMessage("当前课程id未查询到，更新失败!!");
            }
        }catch (Exception e){
            log.info("更新状态失败!!");
            apiResult.setSuccess(false);
            apiResult.setCode(ResultCodeEnum.FAILURE.getCode());
            apiResult.setMessage("更新课程状态失败!!");
        }
        return apiResult;
    }

    @Override
    public ApiResult retContent(CourseIdDTO courseIdDTO) {
        ApiResult apiResult = new ApiResult();
        String id = courseIdDTO.getId();
        try {
            CourseEntity courseId = courseMapper.selectOne(new LambdaQueryWrapper<CourseEntity>().eq(CourseEntity::getId, id));
            if (courseId != null) {
                CourseIdDTO courseContent = new CourseIdDTO();
                courseContent.setContent(courseId.getContent());
                apiResult.setData(courseContent);
                apiResult.setSuccess(true);
                apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                apiResult.setMessage("获取课程内容成功!!");
            } else {
                log.info("id获取课程失败!!");
                apiResult.setSuccess(false);
                apiResult.setCode(ResultCodeEnum.FAILURE.getCode());
                apiResult.setMessage("id获取课程失败,没有查到courseId!!");
            }
        }catch (Exception e){
            log.info("查询内容失败!!");
            apiResult.setSuccess(false);
            apiResult.setCode(ResultCodeEnum.FAILURE.getCode());
            apiResult.setMessage("查询课程内容信息失败!!");
        }
        return apiResult;
    }

    /**
     * 获取子节点信息
     * @param dto
     */
    private void getChild(CategoryAfterDTO dto){
       List<CategoryAfterDTO> childs = listDTO(dto.getId());
       dto.setChildren(childs);
       for (CategoryAfterDTO childCategory: childs){
           getChild(childCategory);
       }
    }
    private List<CategoryAfterDTO> listDTO(String pid){
        List<CategoryEntity> list = categoryMapper.selectList(new LambdaQueryWrapper<CategoryEntity>().eq(CategoryEntity::getPid, pid));;
        List<CategoryAfterDTO> result = new ArrayList<>();
        list.forEach(entity ->{
            CategoryAfterDTO dto = new CategoryAfterDTO();
            BeanUtil.copyProperties(entity,dto);
            result.add(dto);
        });
        return result;
    }
}
